package com.joysuch.wwyt.common.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.zlg.common.enums.BusinessTypeEnum;
import cn.zlg.common.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.joysuch.wwyt.alert.service.NoticeWaitingTriggerListService;
import com.joysuch.wwyt.bp.constant.AppNotifyContentPre;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.common.entity.CommonBusinessNotice;
import com.joysuch.wwyt.common.enums.AppBusinessNoticeTypes;
import com.joysuch.wwyt.common.mapper.AppBusinessNoticeMapper;
import com.joysuch.wwyt.common.service.CommonBusinessNoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joysuch.wwyt.common.service.CommonIndexNotifyService;
import com.joysuch.wwyt.core.bean.SimpleSelectListBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.enums.DeleteFlag;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.support.Context;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author heqifeng
 * @since 2022-01-10
 */
@Slf4j
@Service
public class CommonBusinessNoticeServiceImpl extends ServiceImpl<AppBusinessNoticeMapper, CommonBusinessNotice> implements CommonBusinessNoticeService {

    @Autowired
    private AppBusinessNoticeMapper mapper;
    @Autowired
    private CommonIndexNotifyService indexNotifyService;
    @Autowired
    private NoticeWaitingTriggerListService triggerService;
    @Autowired
    private BaseConfigService configService;

    @Override
    public IPage<CommonBusinessNotice> getNoticeType(Integer index, Integer pageNo, Integer size) {
        // bug 29786, 前端传参4-证书管理，接口测当作证书提醒来处理
        if (index == 4) {
            index = 5;
        }
        LambdaQueryWrapper<CommonBusinessNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommonBusinessNotice::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
        wrapper.eq(CommonBusinessNotice::getNoticeUser, Context.getCurrentUserId());
//        if (index!=5){
        wrapper.eq(CommonBusinessNotice::getBusinessType, AppBusinessNoticeTypes.getType(index));
//        }else {
//            //证书提醒和复证提醒
//            wrapper.like(CommonBusinessNotice::getBusinessType, "提醒");
//        }

        wrapper.le(CommonBusinessNotice::getSendTime, DateUtil.now());
        wrapper.orderByDesc(CommonBusinessNotice::getSendTime);
        Page<CommonBusinessNotice> page = new Page<>(pageNo+1,size);
        IPage<CommonBusinessNotice> noticePage = mapper.selectPage(page, wrapper);
        return noticePage;
    }

    @Override
    public List<SimpleSelectListBean> getSubscriptForUnread() {
        List<SimpleSelectListBean> beanList = mapper.selectUnReadCountGroup(Context.getCurrentUserId());
        return beanList;
    }
    @Override
    public List<SimpleSelectListBean> getSubscriptForUnreadList() {
        List<SimpleSelectListBean> beanList = mapper.selectUnReadCountGroupList(Context.getCurrentUserId());
        return beanList;
    }


    @Override
    public List<SimpleSelectListBean> getCountByGroup() {
        return mapper.selectCountGroup(Context.getCurrentUserId());
    }

    @Override
    public boolean readNoticeBatchByType(Integer index, Date sendTime) {
        LambdaQueryWrapper<CommonBusinessNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommonBusinessNotice::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
        wrapper.eq(CommonBusinessNotice::getReaded, Constant.COMMON_SWITCH_OFF);
        wrapper.eq(CommonBusinessNotice::getNoticeUser,Context.getCurrentUserId());
        wrapper.eq(CommonBusinessNotice::getBusinessType, AppBusinessNoticeTypes.getType(index));
        if (sendTime != null) {
            wrapper.le(CommonBusinessNotice::getSendTime,sendTime);
        }
        List<CommonBusinessNotice> list = list(wrapper);
        List<Long> refIds = new ArrayList<>();
        List<Long> needReadIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(e->{
                e.setReaded(Constant.COMMON_SWITCH_ON);
                needReadIds.add(e.getId());
                // app上教育培训模块、隐患排查中的【任务提醒】小类的已读状态需同步到web
                if ((AppNotifyContentPre.TASK_NOTIFY.equals(e.getNoticeTitle()) || AppBusinessNoticeTypes.EDU.getType().equals(e.getBusinessType())) && e.getRefId() != null) {
                    refIds.add(e.getRefId());
                }
            });
            if (!CollectionUtils.isEmpty(refIds)) {
                indexNotifyService.appRead(refIds, list.get(0).getBusinessType(),Context.getCurrentUserId());
            }
            return mapper.updateReadStateByIds(needReadIds) > 0;
        }
        return false;
    }

    @Override
    public boolean deleteNoticeBatch(List<Long> ids) {
        LambdaQueryWrapper<CommonBusinessNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CommonBusinessNotice::getId,ids);
        List<CommonBusinessNotice> notices = list(wrapper);
        List<Long> refIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(notices)) {
            notices.forEach(each -> {
                each.setReaded(Constant.COMMON_SWITCH_ON);
                each.setDeleteFlag(DeleteFlag.DELETED.getCode());
                // app上教育培训模块、隐患排查中的【任务提醒】小类的删除状态需同步到web
                if ((AppNotifyContentPre.TASK_NOTIFY.equals(each.getNoticeTitle())
                        || AppBusinessNoticeTypes.EDU.getType().equals(each.getBusinessType()))
                        && each.getRefId() != null) {
                    refIds.add(each.getRefId());
                }
            });
            if (!CollectionUtils.isEmpty(refIds)) {
                indexNotifyService.appDelete(refIds, notices.get(0).getBusinessType(),Context.getCurrentUserId());
            }
            return updateBatchById(notices);
        }
        return false;
    }

    @Override
    public boolean deleteNoticeByType(Integer index) {
        LambdaQueryWrapper<CommonBusinessNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommonBusinessNotice::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
        wrapper.eq(CommonBusinessNotice::getNoticeUser,Context.getCurrentUserId());
        wrapper.eq(CommonBusinessNotice::getBusinessType, AppBusinessNoticeTypes.getType(index));
        List<CommonBusinessNotice> list = list(wrapper);
        List<Long> refIds = new ArrayList<>();
        List<Long> needDeleteIds = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(e->{
                needDeleteIds.add(e.getId());
                // app上教育培训模块、隐患排查中的【任务提醒】小类的删除状态需同步到web
                if ((AppNotifyContentPre.TASK_NOTIFY.equals(e.getNoticeTitle())
                        || AppBusinessNoticeTypes.EDU.getType().equals(e.getBusinessType()))
                        && e.getRefId() != null) {
                    refIds.add(e.getRefId());
                }
            });
            if (!CollectionUtils.isEmpty(refIds)) {
                indexNotifyService.appDelete(refIds, list.get(0).getBusinessType(),Context.getCurrentUserId());
            }
            return mapper.deleteByIds(needDeleteIds) > 0;
        }
        return false;
    }

    @Override
    public boolean deleteByRefIdAndTitle(Long refId) {
        // 取消app个推
        triggerService.deleteByBusinessTypeAndTaskCode(BusinessTypeEnum.INVESTIGATE_TASK_TIME_OUT.getBusinessCode(),refId.toString());
        // 取消app通知
        LambdaQueryWrapper<CommonBusinessNotice> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CommonBusinessNotice::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
        wrapper.eq(CommonBusinessNotice::getNoticeTitle, AppNotifyContentPre.TASK_WILL_TIME_OUT_NOTIFY);
        wrapper.eq(CommonBusinessNotice::getRefId, refId);
        List<CommonBusinessNotice> list = list(wrapper);
        if (!CollectionUtils.isEmpty(list)) {
            List<Long> deleteIds = list.stream().filter(e -> e.getSendTime().after(new Date())).map(CommonBusinessNotice::getId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(deleteIds)) {
                return mapper.deleteByIds(deleteIds) > 0;
            }
        }
        return false;
    }

    @Scheduled(cron = "0 0 2 * * ?")
    public void deleteNotify() {
        int day = 30;
        BaseConfig config = configService.findFirstConfig(BaseConfigCodes.READED_NOTIFY_KEEP_DAY);
        if (null != config) {
            String value = config.getValue();
            if (StringUtils.isNotBlank(value)) {
                try {
                    int configDay = Integer.parseInt(value);
                    day = configDay >= 1 ? configDay : day;
                }catch (Exception e) {
                    log.info("readedNotifyKeepDay config error: {}",value);
                }
            }
        }
        DateTime line = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), (day - 1) * -1);
        // 删除个推
        deleteAncientGeTui(line);
        //删除培训通知
        deleteTrainingNotify(line);
        // 删除app通知
        deleteAncientAppNotify(line);
        // 删除web通知
        deleteAncientWebNotify(line);
    }

    private void deleteTrainingNotify(Date line) {
        mapper.deleteTrainingAppNotify(line);
        mapper.deleteTrainingWebNotify(line);
    }

    @Override
    public void deleteNotifyByDay(Integer day) {
        DateTime line = DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), (day - 1) * -1);
        // 删除个推
        deleteAncientGeTui(line);
        // 删除app通知
        deleteAncientAppNotify(line);
        // 删除web通知
        deleteAncientWebNotify(line);
    }

    private void deleteAncientGeTui(Date line) {
        mapper.deleteGeTui(line);
    }

    private void deleteAncientAppNotify(Date line) {
        mapper.deleteAppNotify(line);
    }

    private void deleteAncientWebNotify(Date line) {
        mapper.deleteWebNotify(line);
    }

}
